package com.atguigu.bigdata.scala.mytest.chapter05

object Test4 {
    def main(args: Array[String]): Unit = {
      def fun1():Unit={
        println("123")
      }
      //因为没有参数所以这个表示调用
      val f1 =fun1
      //()的作用时调用函数
      val f11 =fun1()

      println("==========函数作为对象为变量赋值==========")
      def fun2(age:Int):Int={
        age+10
      }
      //调用
      val f2=fun2(1)
      println(f2)
      //赋值给变量
      val f22 = fun2 _
      //入参为int,出参为int的函数fun2作为对象赋值给变量f222
      val f222: (Int)=>Int = fun2
      //通过变量调用
      println(f22(10))
      println(f222(100))

      println("==========函数作为参数传入其他函数==========")
      def a(x:Int,y:Int):Int={
        x+y
      }
      def b(str:String,a:Int):String={
        str+a
      }
      //f:(Int,Int)=>Int 传入一个变量f,f为函数,这个函数的入参为(Int,Int),出参为Int
      def test3( f:(Int,Int)=>Int ):Unit={
        val result: Int = f(10,20)
        println(result)
      }
      def test4(f:(String,Int)=>String):Unit={
        val str: String = f("zhangsan",18)
        println(str)
      }
      //直接传入函数
      test3(a)
      test4(b)
      //可以使用匿名函数直接传参,相当于a方法没名字
      test3((x:Int,y:Int)=>{x*y})
      test4((str:String,a:Int)=>{str+a+"Hello"})
      //匿名函数由于参数类型可以由test3推断出来,参数按照顺序只使用一次,那么可以用_代替
      test3(_*_)
      test4(_+_+"Hello")

      test4((str:String,a:Int)=>{
        println(str.substring(0,3))
        "aaa"
      })
      // 在匿名函数使用时，下划线不能调用其中参数的属性或方法
      //test4( println(_.substring) ) (X)
      test4(_.substring(0,3)+_)


      println("==========函数嵌套==========")
      def test22(): Unit = {
        //函数fun22的作用域为当前函数test22
        def fun22(): Unit = {
          println("函数嵌套")
        }
        fun22()
      }
      test22()

      println("==========函数作为返回值==========")
      def fun3(x:Int)={
          println(x)
          def funA(y:Int)={
              println(x+y)
              //两个参数,f为函数
              def funB(z:Int,f:(Int,Int,Int)=>Int)={
                f(x,y,z)
              }
              funB _
          }
          //函数funA作为返回值返回
          funA _
      }
      //fun3(1)调用函数fun3返回值为一个函数funA,继续调用fun3(1)(2)返回funB,继续调用fun3(1)(2)(3)返回 x+y+z
      val i: Int = fun3(1)(2)(3,(x:Int,y:Int,z:Int)=>{x+y+z})
      println(i)
      println("==================================")
      val e: Int = fun3(1)(2)(3,_+_+_)
      println(e)









    }

}
